/*
 * FILE: lsm.c
 *
 * Add LSM hooks
 */

#include <linux/lsm_hooks.h>

#include "get_symbol.h"
#include "lsm.h"
#include "write_perm.h"
#include "lsm_zds_hooks.h"

#define BUF_SZ 1024
#define ZDS_HOOK_INIT(HEAD, HOOK)		\
{ .head = &zds_security_hook_heads.HEAD,	\
	.hook = { .HEAD = HOOK } }

static void zds_add_hook(struct security_hook_list *hook){
	hlist_add_tail_rcu(&hook->list, hook->head);
}

static void zds_del_hook(struct security_hook_list *hook){
	hlist_del_rcu(&hook->list);
}


struct security_hook_heads zds_security_hook_heads;
static struct security_hook_list zds_hooks[] = {
	ZDS_HOOK_INIT(file_open, my_file_open),
	//ZDS_HOOK_INIT(file_permission, my_file_permission),
};

int zds_hook_init(void){
	int i;

	for(i = 0; i < ARRAY_SIZE(zds_hooks); i++){
		zds_hooks[i].head = ((void *) orig_security_hook_heads)
					+ ((unsigned long)zds_hooks[i].head)
					- ((unsigned long)&zds_security_hook_heads);
	}

	for(i = 0; i < ARRAY_SIZE(zds_hooks); i++){
		zds_add_hook(&zds_hooks[i]);
	}

	return 0;
}

int zds_hook_exit(void){
	int i;

	for(i = 0; i < ARRAY_SIZE(zds_hooks); i++){
		zds_del_hook(&zds_hooks[i]);
	}

	return 0;
}
